package cn.ug.info.service.impl;

import cn.ug.aop.RemoveCache;
import cn.ug.aop.SaveCache;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.status.DeleteStatus;
import cn.ug.core.ensure.Ensure;
import cn.ug.info.bean.ArticleClassBean;
import cn.ug.info.bean.status.ShowStatus;
import cn.ug.info.mapper.ArticleClassMapper;
import cn.ug.info.mapper.entity.ArticleClass;
import cn.ug.info.service.ArticleClassService;
import cn.ug.service.impl.BaseServiceImpl;
import cn.ug.util.UF;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.dozer.DozerBeanMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

import static cn.ug.config.CacheType.OBJECT;
import static cn.ug.config.CacheType.SEARCH;

/**
 * @author kaiwotech
 */
@Service
public class ArticleClassServiceImpl extends BaseServiceImpl implements ArticleClassService {
	
	@Resource
	private ArticleClassMapper articleClassMapper;

	@Resource
	private DozerBeanMapper dozerBeanMapper;

	@Override
	@RemoveCache(cleanSearch = true)
	public int save(ArticleClassBean entityBean) {
		// 数据完整性校验
		if(null == entityBean || StringUtils.isBlank(entityBean.getTitle())) {
			Ensure.that(true).isTrue("11000401");
		}
		if(exists(entityBean, entityBean.getId())){
            // 该数据已存在
        	Ensure.that(true).isTrue("00000004");
        }
		ArticleClass entity = dozerBeanMapper.map(entityBean, ArticleClass.class);
		if(StringUtils.isBlank(entity.getId())) {
			entity.setId(UF.getRandomUUID());
		}
		// 设置级别
		entity.setLayer(findSelfLayer(entityBean.getSupLayer()));
		articleClassMapper.insert(entity);

        return 0;
	}

	@Override
	@RemoveCache(cleanSearch = true, cleanObjectByKeyPosition = 0)
	public int update(String id, ArticleClassBean entityBean) {
        // 数据完整性校验
		if(null == entityBean || StringUtils.isBlank(entityBean.getId()) || StringUtils.isBlank(entityBean.getTitle())) {
			Ensure.that(true).isTrue("11000401");
		}
		if(exists(entityBean, entityBean.getId())){
			// 该数据已存在
			Ensure.that(true).isTrue("00000004");
		}

		ArticleClass entity = articleClassMapper.findById(entityBean.getId());
		dozerBeanMapper.map(entityBean, entity);

		articleClassMapper.update(entity);
		return 0;
	}

	@Override
	@RemoveCache(cleanSearch = true, cleanObjectByKeyPosition = 0)
	public int delete(String id) {
		if(StringUtils.isBlank(id)) {
			return 0;
		}

		return articleClassMapper.delete(id);
	}

	@Override
	@RemoveCache(cleanSearch = true, cleanObjectByKeyPosition = 0)
	public int deleteByIds(String[] id){
		if(id == null || id.length<=0){
			return 0;
		}

		return articleClassMapper.deleteByIds(id);
	}

	@Override
	@RemoveCache(cleanSearch = true, cleanObjectByKeyPosition = 0)
	public int removeByIds(String[] id) {
		if(id == null || id.length<=0){
			return 0;
		}

		return articleClassMapper.updateByPrimaryKeySelective(
				getParams()
						.put("id", id)
						.put("deleted", DeleteStatus.YES)
						.toMap()
		);
	}

	@Override
	@SaveCache(cacheType = SEARCH)
	public boolean exists(ArticleClassBean entityBean, String id) {
		if(null == entityBean || StringUtils.isBlank(entityBean.getTitle())) {
			return false;
		}

		int rows = articleClassMapper.exists(
				getParams()
						.put("title", entityBean.getTitle())
						.put("code", entityBean.getCode())
						.put("id", id)
						.toMap()
		);
		return rows > 0;
	}

	@Override
	@SaveCache(cacheType = OBJECT)
	public ArticleClassBean findById(String id) {
		if(StringUtils.isBlank(id)) {
			return null;
		}

		ArticleClass entity = articleClassMapper.findById(id);
		if(null == entity) {
			return null;
		}

		ArticleClassBean entityBean = dozerBeanMapper.map(entity, ArticleClassBean.class);
		entityBean.setAddTimeString(UF.getFormatDateTime(entity.getAddTime()));
		entityBean.setModifyTimeString(UF.getFormatDateTime(entity.getModifyTime()));
		return entityBean;
	}

	@Override
	@SaveCache(cacheType = SEARCH)
	public ArticleClassBean findByLayer(String layer) {
		if(StringUtils.isBlank(layer)) {
			return null;
		}
		ArticleClassBean entityBean = new ArticleClassBean();
		try{
			List<ArticleClassBean> list = findList(null, null, "", "local", layer, ShowStatus.SHOW, null);
			if(null == list || list.size() <= 0){
				return null;
			}
			entityBean = list.get(0);
		}catch(Exception e){
			getLog().error(e.getMessage());
		}
		return entityBean;
	}

	@Override
	public ArticleClassBean findByCode(String code) {
		if(StringUtils.isBlank(code)) {
			return null;
		}
		ArticleClassBean entityBean = new ArticleClassBean();
		try{
			List<ArticleClassBean> list = findList(null, null, code, null, null, ShowStatus.ALL, null);
			if(null == list || list.size() <= 0){
				return null;
			}
			entityBean = list.get(0);
		}catch(Exception e){
			getLog().error(e.getMessage());
		}
		return entityBean;
	}

	private String findSelfLayer(String supLayer) {
		if(StringUtils.isBlank(supLayer)) {
			supLayer = "";
		}

		List<ArticleClassBean> list = findList(null, null, null, "next", supLayer, null, null);
		if(null == list || list.isEmpty()) {
			return supLayer + "100";
		}

		// 获取最大的一个节点
		String selfLayer = "";
		for(ArticleClassBean o : list){
			if(StringUtils.isBlank(selfLayer) || selfLayer.compareTo(o.getLayer()) < 0){
				selfLayer = o.getLayer();
			}
		}

		if(StringUtils.isBlank(selfLayer ) || selfLayer.length() < 3) {
			return supLayer + "100";
		}

		String leftLayer = selfLayer.substring(0, selfLayer.length()-3);
		String maxNodeLayer = selfLayer.substring(selfLayer.length()-3);
		selfLayer = leftLayer + (UF.toInt(maxNodeLayer) + 1);
		return selfLayer;
	}

	@Override
	@SaveCache(cacheType = SEARCH)
	public List<ArticleClassBean> findListByLayer(String layer) {
		if(StringUtils.isBlank(layer)) {
			layer = "";
		}

		try {
			return findList(null, null, null, "next", layer, ShowStatus.SHOW, null);
		} catch (Exception e) {
			getLog().error(e.getMessage());
		}
		return null;
	}

	@Override
	@SaveCache(cacheType = SEARCH)
	public List<ArticleClassBean> findListByAllLayer(String layer) {
		if(StringUtils.isBlank(layer)) {
			layer = "";
		}
		List<ArticleClassBean> list = findListByLayer(layer);
		if(null == list || list.isEmpty()) {
			return null;
		}

		List<ArticleClassBean> dataList = new ArrayList<>();
		for(ArticleClassBean o : list) {
			dataList.add(o);
			List<ArticleClassBean> list2 = findListByAllLayer(o.getLayer());
			if(null == list2 || list2.isEmpty()){
				continue;
			}
			dataList.addAll(list2);
		}
		return dataList;
	}

	@Override
	@SaveCache(cacheType = SEARCH)
	public List<ArticleClassBean> findList(String order, String sort, String code, String layerMark, String layer, Integer showInNav, String keyword){
		return query(order, sort, code, layerMark, layer, showInNav, keyword);
	}

	@Override
	@SaveCache(cacheType = SEARCH)
	public DataTable<ArticleClassBean> query(String order, String sort, int pageNum, int pageSize, String code, String layerMark, String layer, Integer showInNav, String keyword){
		Page<ArticleClassBean> page = PageHelper.startPage(pageNum, pageSize);
		List<ArticleClassBean> list = query(order, sort, code, layerMark, layer, showInNav, keyword);
		return new DataTable<>(page.getPageNum(), page.getPageSize(), page.getTotal(), list);
	}

	/**
	 * 获取数据列表
	 * @param order				排序字段
	 * @param sort				排序方式 desc或asc
	 * @param code				编号
	 * @param layerMark			层级标志(local：本级   next：本级的下一级[为空顶级]  all：本级下的所有级[为空所有])
	 * @param layer				层级
	 * @param showInNav			是否显示
	 * @param keyword			关键字
	 * @return					列表
	 */
	private List<ArticleClassBean> query(String order, String sort, String code, String layerMark, String layer, Integer showInNav, String keyword){
		List<ArticleClassBean> dataList = new ArrayList<>();
		List<ArticleClass> list = articleClassMapper.query(
				getParams(keyword, order, sort)
						.put("code", code)
						.put("layerMark", layerMark)
						.put("layer", layer)
						.put("showInNav", showInNav)
						.toMap());
		for (ArticleClass o : list) {
			ArticleClassBean objBean = dozerBeanMapper.map(o, ArticleClassBean.class);
			objBean.setAddTimeString(UF.getFormatDateTime(o.getAddTime()));
			objBean.setModifyTimeString(UF.getFormatDateTime(o.getModifyTime()));
			dataList.add(objBean);
		}
		return dataList;
	}

}

